//------------------------------------------------------------------------------
// TestCase Template
// author Zhang Wei on 2014.10.01
// Tested successfully.
//
// modified by zhangwei on 2014.10.01
// - revised.
//------------------------------------------------------------------------------

// Save the URL prefix of the current webapp

var config = {
    base: "/site/api/"
};

//------------------------------------------------------------------------------
// Service Layer
// for business logic including data access and network communication. 
//------------------------------------------------------------------------------

window.TestCaseTemplateModel = Backbone.Model.extend({

	urlRoot : config.base + "wines",
	
	defaults : {
		"id" : null,
		"name" : "",
		"grapes" : "",
		"country" : "USA",
		"region" : "California",
		"year" : "",
		"description" : "",
//		"picture" : ""                 
	},

	initialize : function() {
		this.bind('validate', function(model, error) {
			alert(error);
		});
	},
	
	// The returned string will be pop up by the browser to notify the user.
	validate : function(attributes) {
		if (attributes.name == '') {
			return "name can't be null"; 
		}
	}
});

// The "client" mode means the collection are fully on the client side. 
// The mode should be "client" to enable client side caching for paging.
//
window.TestCaseTemplateService = Backbone.PageableCollection.extend({
	model : TestCaseTemplateModel,
	url : config.base + "wines",
	state : {
		pageSize : 10
	},
	mode : "client" 
});

//------------------------------------------------------------------------------
// View Layer
// for user interaction. Including render the data in the models to webpage
// and accepting the page input to model for saving. 
//------------------------------------------------------------------------------

// In order to guarantee releasing resources when view is closed
//
Backbone.View.prototype.close = function() {
	console.log('Closing view ' + this);
	if (this.beforeClose) {
		this.beforeClose();
	}
	this.remove();
	this.unbind();
};


window.TestCaseTemplateView = Backbone.View.extend({
	
    events: {
        "change input": "onInputChange",
		"click .save": "onSave",
		"click .cancel": "onCancel"
    },

    initialize: function() {
    	this.template = _.template($('#tpl_itemdetail').html());
		this.model.on("change", this.render, this);
    },
    
    render: function() {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    },

    onInputChange: function(event) {
        var target = event.target;
        console.log('onInputChange: changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
    },

	onSave: function() {
		this.model.set({
			name: $('#name').val(),
			grapes: $('#grapes').val(),
			country: $('#country').val(),
			region: $('#region').val(),
			year: $('#year').val(),
			description: $('#description').val()
		});
		if(!this.model.isValid()){
			alert("Invalid input! Usually due to name can't be empty!");
			return false;
		}
		
		// http://stackoverflow.com/questions/16256635/backbone-model-saving-and-callback-issues
		// The model must belong to the pagable item list
		this.model.save(null, {
			success: function() {
				alert("save successfully!");
				app.navigate('', {trigger: true}); // TODO. should not depends on app in this class
			},
			error: function(error){
				console.log("exception encountered when save data" );
			}
		});

		return false;
	},
	
	onCancel : function(){
		app.navigate('', {trigger :true});
	}
});


window.TestCaseTemplateModalView = Backbone.Modal.extend({

    events: {
        "change input": "change",
		"click .save": "saveWine",
		"click .cancel": "cancel"
    },

	initialize: function() {
    	// this.template = _.template($('#tpl_itemdetail').html());  //use id=editModal instead
    	this.template = _.template($('#modal-template').html());
		this.model.on("change", this.render, this);
    },
    
    cancelEl: '.cancel', // TODO ?
    submitEl: '.save', // TODO ?

    render: function() {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    },

    change: function(event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
    },

	saveWine: function() {
		var self= this;
		this.model.set({
			name: $('#name').val(),
			grapes: $('#grapes').val(),
			country: $('#country').val(),
			region: $('#region').val(),
			year: $('#year').val(),
			description: $('#description').val()
		});
		if(!this.model.isValid()){
			alert("name can't be empty!");
			return false;
		}

		// http://stackoverflow.com/questions/16256635/backbone-model-saving-and-callback-issues
		// The model must belong to the pagable item list
		this.model.save(null, {
			success: function() {
				alert("save successfully!");
				app.navigate('', {trigger: true}); // TODO. should not depends on app in this class
			},
			error: function(error){
				console.log("exception encountered when save data" );
			}
		});

		/*
		if (this.model.isNew()) {
			//pageableTerritories.create(this.model, { // TODO should be pageableWines
			winelist.create(this.model, { // TODO should be pageableWines
				success: function() {
					alert("create successfully!");
					app.navigate('', {trigger: true});
				}
			});
		} else {
			this.model.save(null, { // TODO should be pageableWines
				success: function() {
					alert("save successfully!");
					that.remove();
					app.navigate('', {trigger: true});	
				}
			});
		}
		*/
		
		return false;
	},
	
	cancel : function(){
		app.navigate('', {trigger :true});
	}
});


BackgridDeleteCell = Backgrid.Cell.extend({
	template : _.template('<button class="btn btn-danger">Delete</button>'),
	
	events : {
		"click" : "onDeleteRow"
	},
	
	onDeleteRow : function(e) {
		e.preventDefault();
		// this.model.collection.remove(this.model); },
		this.model.destroy({
			success : function(model, response) {
				alert('Wine deleted successfully ' );
			},
			error: function(error){
					console.log("exception encountered when delete data" );
			}
		});
		return false;
	},
	
	render : function() {
		this.$el.html(this.template());
		this.delegateEvents();
		return this;
	}
});

BackgridEditCell = Backgrid.Cell.extend({

	// template : _.template('<a href="#wines/<%= this.model.id %>" class="btn btn-primary">Edit</a>'),
	template : _.template('<button class="btn btn-primary edit">Edit</button>'),
	
	events : {
		"click .edit" : "onEditRow"
	},
/*	
	onEditRow : function(e) {
		e.preventDefault();
		//app.navigate("wines/:id", {trigger: true}); 
		app.navigate("wines/" + this.model.id, {trigger: true}); 
		return false;
	},
*/	
	onEditRow: function(){
		var m = this.model;
		var itemview = new TestCaseTemplateModalView({model: m});
		console.log("onEditRow()");
		$("#showEditModal").html(itemview.render().el);
	},

	render : function() {
		this.$el.html(this.template());
		this.delegateEvents();//代理未来将要的events，例如这里是edit事件
		return this;
	}
});


BackgridColumns = [{
		// enable the select-all extension of the backgrid component
		name : "",
		cell : "select-row",
		headerCell : "select-all"
	}, {
		name : "id",
		label : "ID",
		editable : false,
		cell : Backgrid.IntegerCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "name",
		label : "Name",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "grapes",
		label : "Grapes",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "country",
		label : "Country",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "region",
		label : "Region",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "year",
		label : "Year",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "description",
		label : "Description",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "delete",
		label : "",
		editable : false,
		cell : BackgridDeleteCell
	}, {
		name : "edit",
		label : "",
		editable : false,
		cell : BackgridEditCell
	} ];



//
//
//window.WineCollectionActionView = Backbone.View.extend({
//    tagName: "div", 
//    initialize: function() {
//    	this.template = _.template($("#tpl_actionlist").html());
//    },
//    render: function(eventName) {
//    	$(this.el).html(this.template());
//		return this;
//    },
//
//    events: {
//		"click .addnew": "newWine",
//		"click .deleteselected": "deleteSelected"
//    },
//
//    newWine: function(event) {
//    	
//    },
//    
//    deleteSelected: function(event){
//    	alert("view: deleteSelected");
//    }
//});


//Set up a grid to use the pageable collection
window.TestCaseTemplateCollectionView = Backbone.View.extend({
	
	grid: Backgrid.Grid,
	
	// The el and model object are passed in when instantiate this object(new this object).
	// model: winelist,
	
	events:{
		'click #addnew': 'onAddnew',
		'click #deleteselected': 'onDeleteSelected',
		'click #openmodal': 'onModalAddNew',
	},
	
	initialize: function() {
		console.log("TestCaseTemplateCollectionView initialized!");
		
		this.template = _.template($("#tpl_itemlist").html());
		
		/*
		this.model.on("change", this.render, this);
		*/
		
		// this.on("reset", function(collection){
		// 	this.render();
		// });
	},

	render: function(){
		grid = new Backgrid.Grid({
			columns: BackgridColumns,
			collection: this.model 
		});

		//this.$el.html(this.template());
		//$(this.el).html(this.template(this.model.toJSON()));
		$(this.el).html(this.template());

		$("#backgrid").html( grid.render().el );
		
		var filter = new Backgrid.Extension.ClientSideFilter({
			collection: this.model,
			fields: ['description']
		});
		$("#backgrid").prepend(filter.render().el);
		var paginator = new Backgrid.Extension.Paginator({
			collection: this.model
		});
		$("#backgrid").append(paginator.render().el);
		
		return this;
	},
	
	onAddnew: function(){
		console.log("onAddnew: addnew click");
		$('#objecteditor').html( new TestCaseTemplateView({model: new TestCaseTemplateModel()}).render().el );
		app.navigate("wines/", true);
	},
	
	onModalAddNew: function(){
		console.log("onModalAddnew: addnew click");
		var itemview = new TestCaseTemplateModalView({model: new TestCaseTemplateModel()});
		$("#showEditModal").html(itemview.render().el); 
		// app.navigate("wines/", true);
	},

	onDeleteSelected: function(){
		console.log("onDeleteSelected: delete selected click");	

		var selectedModels = grid.getSelectedModels();
		if (selectedModels == null) {
			alert("Please select what you want to delete first!");
		} 
		else if (selectedModels.length > 5){
			alert("This application doesn't allow you delete objects more than 5! You could only select at most 5");
		}
		else{
			_.each(selectedModels, function(model) {
				model.destroy({
					success: function(model,response){
						console.log("delete selected successfully " + model );
					},
					error: function(error){
						console.log("exception encountered when delete data" );
					}
				})
			});
		}
	}
	
});


// Tile is to define an container area for object list, detail and their related 
// operations. It's an integration of object collection view and object item view
// together.
//
window.TestCaseTemplateTileView = Backbone.View.extend({
	
	// The el will be passed when instantiate this object.
	// el: $("#winetile"),
	
	initialize: function() {
		this.template = _.template($("#tpl_winetile").html());

		this.model.fetch({
	 		success : function(collection, resq, options){
	 			console.log('TestCaseTemplateTileView Fetch successfully.');
 		}
 	});

	},

	// Since the container area (tile) may contains serveral views, you should be careful
	// for subview problems. There're some Backbone extensions to help this.
	
	render: function()
	{
		this.$el.html(this.template());

	 	var view = new TestCaseTemplateCollectionView({el:"#objecteditor", model: this.model});
	 	view.render();
	},
	
	/*
	showList: function(){
		$('#objecteditor').html( new TestCaseTemplateCollectionView({}).render().el );
	},
	
	showAddNew: function(){
		$('#objecteditor').html( new TestCaseTemplateView({model: new TestCaseTemplateModel()}).render().el );
	},
	*/
});


//------------------------------------------------------------------------------
// Application Definition (Controller and Router Extension)
//------------------------------------------------------------------------------

var TestCaseTemplateApplication = Backbone.Router.extend({

	// Declare the model variable, so that the view and use it later. 
	// winelist = new window.TestCaseTemplateService(). It's actually the backbone
	// collection.
	winelist: null,
	
	routes : {
		'' : 'getItemList',
		"wines/new" : "addNew",
		//"wines/deleteselected" : "deleteSelected",
		"wines/:id" : "editItemDetail",
	},

	initialize : function() {
		//var winetile = new window.TestCaseTemplateTileView({});
		//winetile.render();
		winelist = new window.TestCaseTemplateService();
	},
	
	showView : function(selector, view) {
		$(selector).empty();
		$(selector).html(view.render().el);
		this.currentView = view;
		return view;
	},
	
	getItemList: function(){
		// attention: I don't know why the backgrid can display data successfully
		// when passing the model here.
		var winetile = new window.TestCaseTemplateTileView({el: "#winetile", model: winelist});
		winetile.render();
		
		// attention you cannot call app.showView() because the return value of render()
		// method seems not appropriate.
		//app.showView('#winetile', new TestCaseTemplateCollectionView());
	},
	
	editItemDetail : function(id) {
		var wine = winelist.get(id);
		if (wine == null)
		{
			alert("editItemDetail: Failed to get the model object! ");
		}
		else{
			app.showView('#objecteditor', new TestCaseTemplateView({model : wine}));
		};
	},
	
	addNew : function() {
		/*
		var wineview = new TestCaseTemplateView({
			el: "itemdetail"
		});
		if (this.currentView)
			this.currentView.close();
		$("itemdetail").html(wineview.render().el);
		this.currentView = wineview;
		return wineview;
		*/

		console.log("router add new");
		// $('#objecteditor').html( new TestCaseTemplateView({model: new TestCaseTemplateModel()}).render().el );

		var itemview = new TestCaseTemplateModalView({model: new TestCaseTemplateModel()});
		// $("#showEditModal").html(itemview.render().el);
		app.showView('#showEditModal', itemview);
		// app.showView('#showEditModal', new TestCaseTemplateModalView({model : new TestCaseTemplateModel()}));
		
		// app.showView('#objecteditor', new TestCaseTemplateView({model : new TestCaseTemplateModel()}));
	},
	
	/*
	deleteSelected : function() {
		console.log("delete selected click");	
		var selectedModels = listview.getSelectedModels();
		if (selectedModels == null) {
			alert("Please select you want to delete!");
			window.history.back();
		} else {
			_.each(selectedModels, function(model) {
//				winelist.remove(model);  change to destroy
				this.model.destroy();
			});
			alert("delete successfully!");
			app.navigate("wines/", true);
		}
	}
	*/
});


$(document).ready(function () {
	app = new TestCaseTemplateApplication();
	Backbone.history.start();

	/*
	$('.open').on('click', function() {
		var itemview = new TestCaseTemplateModalView({model: new TestCaseTemplateModel()});
		$("#showEditModal").html(itemview.render().el); // TODO
	});
	$('.open').click();
	*/

	var TestModal = Backbone.Modal.extend({
		template : _.template($('#tpl_modal_test').html()),
		cancelEl : '.bbm-button'
	});

	$('.open').on('click', function() {

		// Render an instance of your modal
		var modalView = new TestModal();
		$('.appmodal').html(modalView.render().el);

	});
	$('.open').click();
});
